React is a popular library for creating web apps and mobile apps.
In this article, we’ll look at some tips for writing better React apps.
Fix ‘style prop expects a mapping from style properties to values, not a string’ Error
We’ve to pass in an object to the style
prop.
For instance, we can write:
<span style={{ float: 'left', paddingRight: '5px' }} >foo</span>
We pass in an object with camel-cased properties instead of kebab-case.
Also, we can import styles from a file with the import
keyword.
For instance, we can write:
styles.css
.color{
color: "red";
background: "#0f0";
}
Then we write:
import './styles.css';
const Button = (props) => {
return (
<div>
<span className="color">{props.age}</span>
</div>
);
};
const infos = {
age: 20
};
ReactDOM.render(<Button {...infos} />, mountNode);
We import the styles.css
and then the styles will be applied.
React useReducer Async Data Fetch
useReducer
can be used instead of useState
if we’re changing a state that’s set after lots of computation.
If we have complex state logic with multiple sub-values in the state, or when the next state depends on the previous one, then we can use this hook.
For instance, we can write:
const initialState = {};
function reducer(state, action) {
switch (action.type) {
case 'profileReady':
return action.payload;
default:
throw new Error();
}
}
function App(props) {
const [profile, setProfile] = React.useReducer(reducer, initialState);
useEffect(() => {
reloadProfile()
.then((profileData) => {
setProfile({
type: "profileReady",
payload: profileData
});
});
}, []);
return (
<div>{profile.name}</div>
);
}
We have a reducer that sets the state.
And we have an initial state that we can pass in.
We can pass them both into the useReducer
hook.
It returns the state and the state setter function in this order.
Then we can use that with the useEffect
to get data and set it.
The empty array in the 2nd argument make sure that the callback is only run only when the component is loaded.
How to Refresh a Page Using React Router Link
We can reload a page without using anything from React Router.
For instance, we can write:
window.location.reload();
to reload the page.
Create a Nav Bar with React Router
To create a navbar with React Router, we use the components that are bundled with React Router to create the routes.
For instance, we can write:
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
export default function App() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</Router>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Dashboard() {
return <h2>Dashboard</h2>;
}
We create a few components that we use as routes.
Then we use the in the Switch
component to create our routes.
We have the Route
component inside it and we nest the component we want to display inside.
The navbar is created with the nav
component.
And inside it, we have the Link
components to create the links to display the route components.
to
is the path of the component that we want to display.
And it should match one of the path
values in the Switch
.
To do navigation, we can call history.push
to navigate.
For instance, we can write:
<a onClick={() => history.push('dashboard') }>Dashboard</a>
to navigate programmatically.
Assign the Correct Typing to React.cloneElement When Giving Properties to Children
We can set the type of the child component to the React.ReactElement
type.
For instance, we can write:
return React.cloneElement(child as React.ReactElement<any>, {
name: this.props.name,
age: this.props.age
});
if child
is an element.
We can also use the isValidElement
type guard.
For example, we can write:
if (React.isValidElement(child)) {
return React.cloneElement(child, {
name: this.props.name,
age: this.props.age
});
}
This will let the TypeScript compiler determine the type automatically without adding any data type assertions.
Conclusion
cloneElement
can be used with child elements in React by setting the right type or using a type guard.
Styling can be done with various items.
We can create a navbar easily with React Router.